package com.lbt.framework.jackson;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.lbt.framework.jackson.result.ObjectResult;

public class HibernateObjectMapper extends ObjectMapper {
	
	private static final long serialVersionUID = 1L;
	
	public HibernateObjectMapper() {
		
		//setSerializationInclusion(Include.NON_EMPTY);
		
		disable(SerializationFeature.WRITE_NULL_MAP_VALUES);
		disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		enable(SerializationFeature.WRITE_ENUMS_USING_INDEX);
		
		disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		disable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);
		enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL);
		
		//disable(MapperFeature.AUTO_DETECT_CREATORS);
		//disable(MapperFeature.AUTO_DETECT_FIELDS);
		//disable(MapperFeature.AUTO_DETECT_GETTERS);
		//disable(MapperFeature.AUTO_DETECT_IS_GETTERS);
		//disable(MapperFeature.AUTO_DETECT_SETTERS);
		
		//configure(JsonGenerator.Feature.ESCAPE_NON_ASCII,true);
	}
	
	@Override
	public void writeValue(JsonGenerator jgen, Object value) throws IOException,
			JsonGenerationException, JsonMappingException {
		ObjectWriter ow;
		if (null != (ow = getCustomeWirter(value))) {
			ow.writeValue(jgen, value);
			return;
		} 
		super.writeValue(jgen, value);
	}
	
	@Override
	public void writeValue(File resultFile, Object value) throws IOException,
			JsonGenerationException, JsonMappingException {
		ObjectWriter ow;
		if (null != (ow = getCustomeWirter(value))) {
			ow.writeValue(resultFile, value);
			return;
		}
		super.writeValue(resultFile, value);
	}

	@Override
	public void writeValue(OutputStream out, Object value) throws IOException,
			JsonGenerationException, JsonMappingException {
		ObjectWriter ow;
		if (null != (ow = getCustomeWirter(value))) {
			ow.writeValue(out, value);
			return;
		}
		super.writeValue(out, value);
	}

	@Override
	public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException,
			JsonMappingException {
		ObjectWriter ow;
		if (null != (ow = getCustomeWirter(value))) {
			ow.writeValue(w, value);
			return;
		}
		super.writeValue(w, value);
	}

	@Override
	public String writeValueAsString(Object value) throws JsonProcessingException {
		ObjectWriter ow;
		if (null != (ow = getCustomeWirter(value))) {
			return ow.writeValueAsString(value);
		}
		return super.writeValueAsString(value);
	}

	@Override
	public byte[] writeValueAsBytes(Object value) throws JsonProcessingException {
		ObjectWriter ow;
		if (null != (ow = getCustomeWirter(value))) {
			return ow.writeValueAsBytes(value);
		}
		return super.writeValueAsBytes(value);
	}
	
	private ObjectWriter getCustomeWirter(Object value) {
		if (ObjectResult.class.isAssignableFrom(value.getClass())) {
			ObjectResult<?> result = (ObjectResult<?>)value;
			FilterProvider provider = result.getFilter();
			ObjectWriter ow = this.writer();
			if (null != provider) {
				ow = ow.with(provider);
				return ow;
			}
		}
		return null;
	}
}
